package com.tianji.remark.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.tianji.api.dto.remark.LikedTimesDTO;
import com.tianji.common.autoconfigure.mq.RabbitMqHelper;

import com.tianji.common.utils.BeanUtils;
import com.tianji.common.utils.StringUtils;
import com.tianji.common.utils.UserContext;
import com.tianji.remark.domain.dto.LikeRecordFormDTO;
import com.tianji.remark.domain.po.LikedRecord;
import com.tianji.remark.mapper.LikedRecordMapper;
import com.tianji.remark.service.ILikedRecordService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import static com.tianji.common.constants.MqConstants.Exchange.LIKE_RECORD_EXCHANGE;
import static com.tianji.common.constants.MqConstants.Key.LIKED_TIMES_KEY_TEMPLATE;

/**
 * <p>
 * 点赞记录表 服务实现类
 * </p>
 *
 * @author yangyu
 * @since 2023-07-28
 */
@Service
@RequiredArgsConstructor
public class LikedRecordServiceImpl extends ServiceImpl<LikedRecordMapper, LikedRecord> implements ILikedRecordService {

    private final RabbitMqHelper rabbitMqHelper;

    /**
     * 点赞或取消
     *
     * @param likeRecordDTO 点赞记录表单实体
     */
    @Override
    public void addLikeRecord(LikeRecordFormDTO likeRecordDTO) {

        //1.判断是点赞还是取消点赞：(true点赞)(false取消点赞)
        boolean success = likeRecordDTO.getLiked() ? like(likeRecordDTO) : cancel(likeRecordDTO);

        //2.判断是否执行成功，如果失败，则直接结束
        if (!success) {
            return;
        }

        // 3.如果执行成功，统计当前业务id下的点赞数量
        int likedTimes = count(Wrappers.<LikedRecord>lambdaQuery()
                .eq(LikedRecord::getBizId, likeRecordDTO.getBizId()));

        // 4.发送MQ通知,到具体的业务系统，更新点赞数量
        rabbitMqHelper.send(LIKE_RECORD_EXCHANGE, //Exchange:like.record.topic
                StringUtils.format(LIKED_TIMES_KEY_TEMPLATE, likeRecordDTO.getBizType()), //RoutingKey：{问答或笔记}.times.changed
                LikedTimesDTO.of(likeRecordDTO.getBizId(), likedTimes));  //业务id，点赞数量
    }


    /**
     * 批量查询点赞状态
     *
     * @param bizIds 业务id集合
     * @return 已点赞的业务id集合
     */
    @Override
    public Set<Long> isBizLiked(List<Long> bizIds) {
        //1.获取登录用户id
        Long userId = UserContext.getUser();

        //2.根据业务id集合，批量查询当前用户的点赞记录(已点赞)
        List<LikedRecord> list = list(Wrappers.<LikedRecord>lambdaQuery()
                .eq(LikedRecord::getUserId, userId)
                .in(LikedRecord::getBizId, bizIds));

        //3.将点赞记录集合中的每一个业务id存入Set集合，返回
        //将点赞记录集合中的每一个业务id，使用Set集合收集起来
        return list.stream().map(LikedRecord::getBizId).collect(Collectors.toSet());
    }


    //取消点赞逻辑
    private boolean cancel(LikeRecordFormDTO likeRecordDTO) {
        //1.获取登录用户id
        Long userId = UserContext.getUser();

        //2.取消点赞：直接根据当前用户id，点赞业务id，删除点赞记录
        return remove(Wrappers.<LikedRecord>lambdaQuery()
                .eq(LikedRecord::getUserId, userId) //用户id
                .eq(LikedRecord::getBizId, likeRecordDTO.getBizId())); //点赞业务id
    }


    //点赞逻辑
    private boolean like(LikeRecordFormDTO likeRecordDTO) {
        //1.获取登录用户id
        Long userId = UserContext.getUser();

        //2.查询点赞记录
        int count = count(Wrappers.<LikedRecord>lambdaQuery()
                .eq(LikedRecord::getUserId, userId)
                .eq(LikedRecord::getBizId, likeRecordDTO.getBizId()));

        //3.判断是否存在，如果已经存在，直接结束，后续就没必要统计点赞数量了，因为已经点赞了
        if (count > 0) {
            return false;
        }

        //3.点赞记录不存在，则新增点赞记录
        LikedRecord likedRecord = BeanUtils.copyBean(likeRecordDTO, LikedRecord.class);
        likedRecord.setUserId(userId);
        save(likedRecord);
        return true;
    }
}
